package two.chapter_1.c1_2;

import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

public class Ex1_2_11 {


    public static void main(String[] args) {
        SmartDate date=new SmartDate(3,1,2018);

        StdOut.println(date.dayOfTheWeek());
    }

    private static class SmartDate extends Date {
        private final int val;
        public SmartDate(int month, int day, int year) {
            super(month, day, year);
            if (!DateChecker.month(month) || !DateChecker.day(year,month,day)){
                throw new IllegalArgumentException();
            }

            val= day+month*32+year*512;
        }

        @Override
        int day() {
            return val%32;
        }

        @Override
        int month() {
            return (val/32)%16;
        }

        @Override
        int year() {
            return val/512;
        }


        /**
         * 蔡勒（Zeller）公式，是一个计算星期的公式，随便给一个日期，就能用这个公式推算出是星期几。
         * w=( y+(y/4)+c/4-2c+26(m+1)/10+d-1 ) mod 7
         * @return
         */
        public Week dayOfTheWeek(){
            int y=year();
            int m=month();
            if (m==1){
                y-=1;
                m=13;
            }else if (m==2){
                y-=1;
                m=14;
            }
            y=y%100;
            int d=day();
            int c=y/100;
            Week week=null;
            int w=(y+y/4+c/4-2*c+26*(m+1)/10+d-1) % 7;
            switch (w){
                case 0:
                    week=Week.SUNDAY;
                    break;
                case 1:
                    week=Week.MONDAY;
                    break;
                case 2:
                    week=Week.TUESDAY;
                    break;
                case 3:
                    week=Week.WEDNESDAY;

                    break;
                case 4:
                    week=Week.THURSDAY;
                    break;
                case 5:
                    week=Week.FRIDAY;
                    break;
                case 6:
                    week=Week.SATURDAY;
                    break;

            }
            return week;
        }

        public enum Week{
            SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY
        }
    }




}
